import { DataGridSchema } from '../schema/datagrid';
import { ElementPropertyConfig } from '@farris/ide-property-panel';
import { DataGridProp } from '../property/property-config';
import FdDataGridFieldComponent from './datagrid-field/component/fd-datagrid-field';
import FdCollectionBaseComponent from '../../common/collection-base/fd-collection-base';
import { RowNode } from '@farris/ui-treetable';
import { DataGridContextMenuManager } from '../context-menu/context-menu.manager';
import { DesignerEnvType, DesignViewModelService, DomService, FormComponent } from '@farris/designer-services';
import { ControlService } from '../../../../service/control.service';
import { defaultsDeep } from 'lodash-es';
import { NoCodeDataGridProp } from '../property/nocode-property-config';
import { DgControl } from '../../../../utils/dg-control';

export default class FdDataGridComponent extends FdCollectionBaseComponent {

    /** 单列实例集合 */
    gridFieldInstances: FdDataGridFieldComponent[];

    /** 是否启用了卡片式编辑（弹出编辑/侧边栏编辑） */
    private isEnableCardEdit: boolean;

    /** 列表若启用了卡片编辑视图，需要记录当前展示的视图类型 */
    private currentViewShowType = 'grid';

    /** 弹出/侧边栏组件实例 */
    private cardEditComponentInstance: FdCollectionBaseComponent;

    /** 启用卡片式编辑后的视图切换按钮 */
    private toolbarIconData = [];

    get gridViewPanelKey() {
        return 'gridViewPanel';
    }
    get cardViewPanelKey() {
        return 'cardViewPanel';
    }
    get gridViewChangeBtnKey() {
        return 'gridViewChangeBtn';
    }

    constructor(component: any, options: any) {
        super(component, options);
    }

    getDefaultSchema(): any {
        return DataGridSchema;
    }

    getStyles(): string {
        return 'display: flex; flex: 1; padding:0;border:0;position:relative';
    }

    init() {
        this.adaptOldControlSchema();
        this.components = [];
        this.gridFieldInstances = [];
        if (this.component.fields) {
            const options = Object.assign({}, this.options, { parent: this });

            this.component.fields.map(item => {
                const fieldInstance = new FdDataGridFieldComponent(item, options, this);
                this.gridFieldInstances.push(fieldInstance);
            });
        }
        this.components = this.components.concat(this.gridFieldInstances);

    }
    render(): any {
        const cardEditTemplates = this.renderCardEditPanel();

        this.getCustomToolbarConfigs();

        return super.render(this.renderTemplate('DataGrid', {
            component: this.component,
            gridFieldInstances: this.gridFieldInstances,

            isEnableCardEdit: this.isEnableCardEdit,
            currentViewShowType: this.currentViewShowType,
            cardEditTemplates,
            gridViewChangeBtnKey: this.gridViewChangeBtnKey,
            cardViewPanelKey: this.cardViewPanelKey,
            toolbarIconData: this.toolbarIconData,
            gridViewPanelKey: this.gridViewPanelKey
        }));
    }

    /**
     * 元素扩展事件
     */
    attach(element: HTMLElement): Promise<any> {
        const superAttach = super.attach(element);

        // 挂载单列的点击事件
        this.gridFieldInstances.forEach(gridFieldInstance => {
            const itemId = gridFieldInstance.component.id;
            this.loadRefs(element, {
                [itemId]: 'multiple'
            });
            gridFieldInstance.attach(this.refs[itemId][0]);
        });

        // 挂载可拖拽区域，用于从控件工具箱和实体树中拖拽节点
        this.hook('attachComponents', element, [], [], this);

        this.attachCardEditPanel(element);

        this.registerGridFieldDnd();

        this.setContextMenuBasicInfoMap();
        return superAttach;
    }

    private getCustomToolbarConfigs() {
        this.customToolbarConfigs = [
            {
                id: 'gridFieldManager',
                title: '字段维护',
                icon: 'f-icon f-icon-home-setup',
                click: (e) => {
                    e.stopPropagation();
                    this.showFieldManager();
                }
            }
        ];
    }

    onComponentClicked(e?: PointerEvent): void {
        super.onComponentClicked(e);
        // 控件右上角的配置字段图标：只有当前显示Grid视图时才展示
        if (this.element) {
            const fieldManagerBtn = this.element.querySelector('[ref=gridFieldManager].component-settings-button') as HTMLElement;
            if (fieldManagerBtn) {
                fieldManagerBtn.style.visibility = this.isEnableCardEdit && this.component.currentViewShowType !== 'grid' ? 'hidden' : 'visible';
            }
        }
    }
    /**
     * 渲染卡片式编辑视图模板
     */
    private renderCardEditPanel() {

        // 列表启用了卡片式编辑（弹出编辑或者侧边栏编辑）：这种场景里需要同时展示列表和卡片视图。使用浮动的图标来支持切换
        this.isEnableCardEdit = false;
        if (this.component.enableEditByCard !== 'none' && this.component.modalComponentId) {
            const serviceHost = this.options.designerHost;
            const domService = serviceHost.getService('DomService') as DomService;

            const modalComponent = domService.getComponentById(this.component.modalComponentId);
            if (!modalComponent) {
                return;
            }
            this.isEnableCardEdit = true;
            this.currentViewShowType = this.component.currentViewShowType || 'grid';

            // 创建弹出组件实例，这里不能重复创建
            if (!this.cardEditComponentInstance) {
                this.cardEditComponentInstance = this.createComponent(modalComponent, this.options, modalComponent.id, modalComponent.viewModel);
            }
        }


        let cardEditTemplates = '';
        if (this.isEnableCardEdit && this.cardEditComponentInstance) {
            cardEditTemplates = this.cardEditComponentInstance.renderComponents([this.cardEditComponentInstance]);
            this.initEditByCardViewChangeToolbar();
        }

        return cardEditTemplates;
    }

    /**
     * 挂载卡片式式编辑视图
     */
    private attachCardEditPanel(element: HTMLElement) {

        if (this.isEnableCardEdit && this.cardEditComponentInstance) {
            // 挂载视图切换按钮
            this.loadRefs(element, {
                gridViewChangeBtn: 'multiple'
            });
            // 注册视图切换事件
            const changeBtnEles = this.refs[this.gridViewChangeBtnKey];
            if (changeBtnEles && changeBtnEles.length) {
                changeBtnEles.forEach((changeBtnEle, index) => {
                    this.addEventListener(changeBtnEle, 'click', (event) => {
                        event.preventDefault();
                        event.stopPropagation();

                        this.changeCurrentViewShowType(index);
                    });
                });

            }

            // 挂载卡片视图内控件
            this.loadRefs(element, {
                [this.gridViewPanelKey]: 'single',
                [this.cardViewPanelKey]: 'single'
            });
            const cardEditEle = this.refs[this.cardViewPanelKey];
            if (cardEditEle) {
                this.cardEditComponentInstance.attach(cardEditEle);
            }
        }
    }

    /**
     * 组装属性面板配置数据
     */
    getPropertyConfig(): ElementPropertyConfig[] {
        const serviceHost = this.options.designerHost;

        if (this.envType === DesignerEnvType.noCode) {
            const prop: NoCodeDataGridProp = new NoCodeDataGridProp(serviceHost, this.viewModelId, this.componentId);
            const propertyConfig: ElementPropertyConfig[] = prop.getPropConfig(this.component);
            return propertyConfig;
        } else {
            const prop: DataGridProp = new DataGridProp(serviceHost, this.viewModelId, this.componentId);
            const propertyConfig: ElementPropertyConfig[] = prop.getPropConfig(this.component);
            return propertyConfig;
        }
    }


    /**
     * 组装右键菜单
     * @param rowNode 组件在控件树上对应的行数据
     */
    resolveContextMenuConfig(rowNode: RowNode) {
        const menuManager = new DataGridContextMenuManager(this, rowNode);
        return menuManager.setContextMenuConfig();
    }

    /**
     * 初始展示类型切换按钮
     */
    private initEditByCardViewChangeToolbar() {
        switch (this.component.enableEditByCard) {
            case 'modal': {
                this.toolbarIconData = [
                    {
                        type: 'grid',
                        title: '表格视图',
                        icon: 'f-icon f-icon-grid-layout'
                    },
                    {
                        type: 'modal',
                        title: '弹出卡片视图',
                        icon: 'f-icon f-icon-group'
                    }
                ];
                break;
            }
            case 'sidebar': {
                this.toolbarIconData = [
                    {
                        type: 'grid',
                        title: '表格视图',
                        icon: 'f-icon f-icon-grid-layout'
                    },
                    {
                        type: 'sidebar',
                        title: '侧边栏卡片视图',
                        icon: 'f-icon f-icon-group'
                    }
                ];
                break;
            }
            default: {
                this.toolbarIconData = [];
            }
        }
    }
    /**
     * 切换显示类型
     * @param index 图标索引
     */
    private changeCurrentViewShowType(index: number) {
        const type = this.toolbarIconData[index].type;
        if (this.currentViewShowType === type) {
            return;
        }
        this.currentViewShowType = type;
        this.component.currentViewShowType = type;

        // 切换显示类型
        const gridDiv = this.refs[this.gridViewPanelKey];
        const cardDiv = this.refs[this.cardViewPanelKey];
        switch (type) {
            case 'grid': {
                if (gridDiv) {
                    gridDiv.style = 'display:unset';
                }
                if (cardDiv) {
                    cardDiv.style = 'display:none !important';
                }
                break;
            }
            case 'sidebar': case 'modal': {

                if (gridDiv) {
                    gridDiv.style = 'display:none !important';
                }
                if (cardDiv) {
                    cardDiv.style = 'display:flex';
                }
                break;
            }
        }

        // 切换图标样式
        const changeBtnEles = this.refs[this.gridViewChangeBtnKey];
        if (changeBtnEles && changeBtnEles.length) {
            changeBtnEles.forEach((changeBtnEle: HTMLElement) => {
                const key = changeBtnEle.getAttribute('key');
                if (key === type) {
                    changeBtnEle.classList.add('tile-btn-active');
                } else {
                    changeBtnEle.classList.remove('tile-btn-active');
                }
            });
        }

        // 控件右上角的配置字段图标：只有当前显示Grid视图时才展示
        if (this.element) {
            const fieldManagerBtn = this.element.querySelector('[ref=gridFieldManager].component-settings-button') as HTMLElement;
            if (fieldManagerBtn) {
                fieldManagerBtn.style.visibility = type === 'grid' ? 'visible' : 'hidden';
            }
        }


    }

    /**
     * 调整列顺序后同步修改DOM结构
     */
    dragGridFieldEnd(e: any) {
        super.dragGridFieldEnd(e);

        const oldIndex = e.oldIndex;
        const newIndex = e.newIndex;
        const item = this.gridFieldInstances[oldIndex];
        this.gridFieldInstances.splice(oldIndex, 1);
        this.gridFieldInstances.splice(newIndex, 0, item);
    }

    /**
     * 适配表单控件的元数据变更
     */
    private adaptOldControlSchema() {
        if (this.component.multiSelect === null) {
            this.component.multiSelect = false;
        }
        if (this.component.fields && this.component.fieldEditable) {
            const injector = this.options.designerHost.getService('Injector');
            const controlService = injector.get(ControlService) as ControlService;

            this.component.fields.forEach(field => {
                if (!field.editor) {
                    return;
                }
                const metadata = controlService.getControlMetaData(field.editor.type);
                field.editor = defaultsDeep(field.editor, metadata);
            });
        }

    }

    /**
     * 设置子表DataGrid展示名称和路径，用于交互面板已绑定事件窗口
     */
    setComponentBasicInfoMap() {
        super.setComponentBasicInfoMap();

        if (!this.belongedCmpInstance || !this.belongedCmpInstance.parent) {
            return;
        }
        const domService = this.options.designerHost.getService('DomService') as DomService;

        const viewModel = domService.getViewModelById(this.belongedCmpInstance.component.viewModel);
        if (!viewModel || viewModel.bindTo === '/') {
            return;
        }
        // 定位父级容器：Tab或者Section
        const cmpRef = this.belongedCmpInstance.parent;
        const cmpRefParent = cmpRef && cmpRef.parent;
        if (!cmpRefParent) {
            return;
        }
        let parentTitle = '';
        let cmpRefParentSchema = cmpRefParent.component;
        // 父级为Tab，需要定位到具体的TabPage
        if (cmpRefParent.type === DgControl.Tab.type && cmpRefParentSchema && cmpRefParentSchema.contents && cmpRefParentSchema.contents.length) {
            cmpRefParentSchema = cmpRefParentSchema.contents.find(tabPage => tabPage.contents && tabPage.contents.find(co => co.id === cmpRef.id));
            if (cmpRefParentSchema) {
                parentTitle = cmpRefParentSchema.title;
            }
        }
        // 父级为Section，直接取section的主标题
        if (cmpRefParent.type === DgControl.Section.type && cmpRefParentSchema.showHeader) {
            parentTitle = cmpRefParentSchema.mainTitle || '';
        }


        if (parentTitle) {
            const showName = this.getControlShowName();
            domService.controlBasicInfoMap.set(this.component.id, {
                showName,
                parentPathName: `${parentTitle} > ${showName}`
            });
        }

    }

    /**
     * 设置列表右键菜单按钮的展示名称和路径，用于交互面板已绑定事件窗口
     */
    private setContextMenuBasicInfoMap() {
        if (!this.component.contextMenuItems || !this.component.contextMenuItems.length) {
            return;
        }
        const domService = this.options.designerHost.getService('DomService') as DomService;
        const dataGridPath = domService.controlBasicInfoMap.get(this.component.id);
        this.component.contextMenuItems.forEach(menuItem => {
            domService.controlBasicInfoMap.set(menuItem.id, {
                showName: menuItem.title,
                parentPathName: `${dataGridPath.parentPathName} > ${menuItem.title}`
            });
        });

    }

    /**
     * 列表删除后事件：若列表启用了弹出编辑，在删除列表时，需要将弹出页面相关的component/viewmodel一起删除
     */
    onRemoveComponent(): void {
        if (!this.component.modalComponentId) {
            return;
        }

        const serviceHost = this.options.designerHost;
        const dgViewModelService = serviceHost.getService('DesignViewModelService') as DesignViewModelService;
        const domService = serviceHost.getService('DomService') as DomService;

        const modalCmp = domService.getComponentById(this.component.modalComponentId);
        if (!modalCmp) {
            return;
        }

        // 删除弹窗内部的全局按钮
        this.deleteGlobalToolbarInModal(modalCmp, domService);

        // 删除弹出组件内部的子组件
        this.deleteModalComponent(modalCmp.contents, dgViewModelService, domService);

        // 删除弹出组件
        dgViewModelService.deleteViewModelById(modalCmp.viewModel);
        domService.deleteComponent(this.component.modalComponentId);



    }

    /**
     * 删除弹出组建内部的子组件
     */
    private deleteModalComponent(contents: any[], dgViewModelService: DesignViewModelService, domService: DomService) {

        if (contents && contents.length) {
            contents.forEach(c => {
                if (c.contents) {
                    this.deleteModalComponent(c.contents, dgViewModelService, domService);
                }

                if (c.type !== DgControl.ComponentRef.type) {
                    return;
                }
                const modalFormCmp = domService.getComponentById(c.component);

                // 删除弹出子组件
                dgViewModelService.deleteViewModelById(modalFormCmp.viewModel);
                domService.deleteComponent(modalFormCmp.id);
            });
        }
    }

    /**
     * 删除弹窗内部的全局按钮
     */
    private deleteGlobalToolbarInModal(modalCmp: FormComponent, domService: DomService) {
        const header = domService.selectNode(modalCmp, item => item.type === DgControl.Header.type);
        const footer = domService.selectNode(modalCmp, item => item.type === DgControl.ModalFooter.type);

        if (!header && !footer) {
            return;
        }
        const toolbar = domService.module.toolbar;


        if (toolbar && toolbar.items && toolbar.items[modalCmp.viewModel]) {
            delete toolbar.items[modalCmp.viewModel];
        }
        if (toolbar && toolbar.configs) {
            Object.keys(toolbar.configs).forEach(showMode => {
                if (toolbar.configs[showMode]) {
                    if (header) {
                        delete toolbar.configs[showMode][header.id];
                    }
                    if (footer) {
                        delete toolbar.configs[showMode][footer.id];
                    }
                }
            });

        }

    }
}
